package plgnet

import (
	"dgo/MyProj/PrjHttpClt"
	"dgo/MyProj/PrjHttpUtils"
	"dgo/goutils/utils"
	"dgo/plg/plgbase"
	"fmt"
	"gitee.com/ymofen/gobase/golog"
	"gitee.com/ymofen/supervalue"
	"sync/atomic"
	"time"
)

type PlgCmdHttpClt struct {
	plgbase.PlgBase
	url                 string
	lastRequestURL      string
	check_list_flag     int
	request_succ_n      int
	startflag           uint32
	last_request_task_t time.Time
	last_resp           string
	last_resp_t         time.Time

	timer *utils.Timer
}

func (this *PlgCmdHttpClt) Request() {
	url := plgbase.ReplacePlaceholderForFileName(this.url)
	json, err := PrjHttpClt.GetUrlAsJSON(url)
	if err != nil {
		golog.Warnf("获取命令数据异常:%s, url:%s", err.Error(), url)
		return
	}

	str := json.AsJSONString(false)
	if this.last_resp == str {
		return
	}

	this.last_resp = json.AsJSONString(false)
	this.last_resp_t = time.Now()

	cmd := json
	if !json.IsArray() {
		cmd = json.ValueByName("list")
		if cmd == nil {
			cmd = json.ValueByName("cmd-list")
		}
	}

	if cmd == nil || cmd.Count() == 0 {
		golog.Warnf("缺少命令数据:%s", json.AsJSONString(false))
		return
	}

	succ_n, errcode, err := plgbase.ReloadPlgFromJSONList(cmd)
	if err != nil {
		golog.Warnf("处理命令异常:(%d)%s", errcode, err.Error())
	}

	if succ_n > 0 {
		this.request_succ_n++
		this.lastRequestURL = url
		golog.Infof("加载成功插件:%d", succ_n)
	}
}

func (this *PlgCmdHttpClt) OnHttpStatus(rec *PlgHttpRec) (rval interface{}, errcode int, err error) {
	itype := rec.QryAsInt("type", 0)
	if itype == 99 {
		json := wrapper.NewSVObject()
		json.SetKeyValue("request_succ_n", this.request_succ_n)
		json.SetKeyValue("startflag", this.startflag)
		json.SetKeyValue("last_request_task_t", utils.DateTimeString2(this.last_request_task_t))
		json.SetKeyValue("last_resp", this.last_resp)
		json.SetKeyValue("last-resp-t", utils.DateTimeString2(this.last_resp_t))
		PrjHttpUtils.JSON2TableRec(rec.RespW, "", json.String())
		//} else if itype == 98 {
		//	rec.ResponseSyncListNEx(this.msglst)
	} else if itype == 1 {
		json := wrapper.NewSVArray()
		//searchval := rec.QryAsString("searchval", "")
		//sn := 0
		//maxn := rec.QryAsInt("n", 100)
		//this.lst.ListRangeV2(func(key, val interface{}) bool {
		//	pojo := val.(*VrsSitePojo)
		//	ok := true
		//	if len(searchval) > 0 {
		//		ok = strings.Contains(pojo.id, searchval)
		//	}
		//	return ok
		//}, func(k0, v0, k1, v1 interface{}) bool {
		//	p0 := v0.(*VrsSitePojo)
		//	p1 := v1.(*VrsSitePojo)
		//	return p0.id < p1.id
		//}, func(key, val interface{}) bool {
		//	sn++
		//	pojo := val.(*VrsSitePojo)
		//	itm := json.AppendObject()
		//	itm.SetKeyValue("sn", sn)
		//	itm.SetKeyValue("id", pojo.id)
		//	return sn < maxn
		//})

		if rec.QryAsInt("json", 0) == 1 {
			PrjHttpUtils.ResponseAsJSON(rec.RespW, json.AsJSONStringEx(false, false))
		} else {
			PrjHttpUtils.JSON2Table(rec.RespW, "", json.AsJSONString(false))
		}
	} else if itype == 2 {
		rec.ResponseText(this.last_resp)
	} else {
		var sb utils.BytesBuilder
		PrjHttpUtils.AppendIndexBody(&sb, "status", "status?type=99")
		//PrjHttpUtils.AppendIndexBody(&sb, "msglist", "status?type=98&n=100&searchval=")
		//PrjHttpUtils.AppendIndexBody(&sb, "lst", "status?type=1&n=100&searchval=")
		PrjHttpUtils.AppendIndexBody(&sb, "last-get", "status?type=2")

		PrjHttpUtils.ResponseBodyHtml(rec.RespW, sb.String())
	}
	return

}

/*
**

	{
	   "url":"http://xxx.xx.xx:xxx/$appuuid$,
	   "check-list":1,  //默认:1
	   "force-reload":1,
	   "reload-interval-secs":0
	}
*/
func (this *PlgCmdHttpClt) ReloadConf(conf *wrapper.SuperValue) error {
	conf.CheckStrFunc("url", func(strv string) {
		this.url = plgbase.ReplacePlaceholderForFileName(strv)
		if this.lastRequestURL != this.url {
			this.request_succ_n = 0
		}
	})

	conf.CheckExistsIntFunc("check-list", func(val int64) {
		this.check_list_flag = int(val)
	})

	if conf.IntByName("force-reload", 0) == 1 {
		this.request_succ_n = 0
		this.last_resp = ""
	}

	if this.timer == nil {
		this.timer = utils.NewTimer()
		this.timer.OnTimer = func(tag interface{}) {
			this.Request()
		}
	}
	this.timer.ConfigInterval(time.Duration(conf.Int64ByName("reload-interval-secs", 0))*time.Second, 0)

	if atomic.CompareAndSwapUint32(&this.startflag, 0, 1) {
		utils.AddTaskFxiedInterval(this, time.Second*10, func() bool {
			this.last_request_task_t = time.Now()
			url := plgbase.ReplacePlaceholderForFileName(this.url)
			if url != this.lastRequestURL {
				this.request_succ_n = 0
			}

			if this.request_succ_n == 0 {
				this.Request()
			}

			return this.startflag == 1
		})
	}
	return nil
}

func (this *PlgCmdHttpClt) OnObjectNotify(sender interface{}, notifytype int, data interface{}) (rval interface{}, err error) {
	if notifytype == utils.NOTIFY_TYPE_SETCONF {
		if conf, ok := data.(*wrapper.SuperValue); ok {
			err = this.ReloadConf(conf)
		} else {
			err = fmt.Errorf("非法的JSON配置")
		}
	} else if notifytype == utils.NOTIFY_TYPE_RELEASE {
		this.startflag = 0
	}
	return
}

func CreateCmdHttpCltPlugFunc(args ...interface{}) (rval interface{}, err error) {
	obj := &PlgCmdHttpClt{}
	if len(args) > 0 {
		if str, ok := args[0].(string); ok {
			obj.PlugId = str
		}
	}
	rval = obj
	return
}
